package com.nq.service.impl;

/**

 * 开发者----股牛网络

 * 联系TG：gncms

 */


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nq.common.ServerResponse;
import com.nq.common.SystemVersionEnum;
import com.nq.dao.*;
import com.nq.dao.stock.StIpoMapper;
import com.nq.dao.stock.UserStockSubscribePaymentMapper;
import com.nq.pojo.*;
import com.nq.pojo.vo.StockSubscribeVo;
import com.nq.service.*;
import com.nq.stock.entity.StIpo;
import com.nq.stock.entity.UserStockSubscribePayment;
import com.nq.utils.DateTimeUtil;
import com.nq.utils.DateUtils;
import com.nq.utils.KeyUtils;
import com.nq.utils.PropertiesUtil;
import com.nq.utils.stock.sina.SinaStockApi;
import com.nq.utils.redis.JsonUtil;
import com.nq.utils.redis.RedisShardedPoolUtils;
import com.nq.utils.stock.GeneratePosition;
import com.nq.vo.stock.StockListVO;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 新股申购
 * @author lr
 * @date 2020/07/24
 */
@Service("IUserStockSubscribeService")
@Slf4j
public class UserStockSubscribeServiceImpl  implements IUserStockSubscribeService {

    @Value("${spring.profiles.active}")
    private String active;

    @Resource
    private UserStockSubscribeMapper userStockSubscribeMapper;

    @Resource
    private UserCashDetailMapper userCashDetailMapper;
    @Autowired
    UserMapper userMapper;

    @Autowired
    ISiteMessageService iSiteMessageService;
    @Autowired
    StockSubscribeMapper stockSubscribeMapper;
    @Autowired
    IUserPositionService iUserPositionService;
    @Autowired
    ISiteProductService iSiteProductService;
    @Autowired
    IUserService iUserService;
    @Autowired
    private IAgentUserService iAgentUserService;
    @Autowired
    IStockService iStockService;
    @Autowired
    ISiteSettingService iSiteSettingService;
    @Autowired
    UserPositionMapper userPositionMapper;
    @Autowired
    IAgentAgencyFeeService iAgentAgencyFeeService;
    @Resource
    private StIpoMapper stIpoMapper;
    @Resource
    private UserStockSubscribePaymentMapper userStockSubscribePaymentMapper;

    // 印度版本一键购买数量为50W
    public static final Integer APPLY_NUM = 500000;

    /**
     * 用户新股申购
     * @param model
     * @return
     */
    @Override
    @Transactional
    public ServerResponse insert(UserStockSubscribe model, HttpServletRequest request) {
        int ret = 0;
        if (model.getIpoId() == null) {
            return ServerResponse.createByErrorMsg("Parameter error");
        }

        String property = PropertiesUtil.getProperty("user.cookie.name");
        String header = request.getHeader(property);
        if (header != null) {
            String userJson = RedisShardedPoolUtils.get(header);
            User user = this.iUserService.getCurrentRefreshUser(request);
            if (user == null){
                return ServerResponse.createBySuccessMsg("Please log in first.");
            }

            // 待补缴金额
            BigDecimal paymentAmount = BigDecimal.ZERO;
            if (null != model.getIpoId()) {

                StIpo ipo = stIpoMapper.selectById(model.getIpoId());
                //实名认证开关
                SiteProduct siteProduct = iSiteProductService.getProductSetting();
                if (siteProduct.getRealNameDisplay() && (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()))) {
                    return ServerResponse.createByErrorMsg("If the order fails, please authenticate with your real name first.");
                }

                //判断休息日不能买入
//                if (siteProduct.getHolidayDisplay()) {
//                    return ServerResponse.createByErrorMsg("周末或节假日不能交易！");
//                }

                //重复申购限制
//                UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.selectOne(new QueryWrapper<UserStockSubscribe>().eq("new_code", model.getNewCode()).eq("user_id", user.getId()));
//                if (userStockSubscribe != null) {
//                    return ServerResponse.createByErrorMsg("请勿重复申购");
//                }

//                if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) {
//                    return ServerResponse.createByErrorMsg("Order failed and account locked");
//                }

                if (ipo == null) {
                    return ServerResponse.createByErrorMsg("New stock code does not exist");
                }

                // 一键申购 默认50W
                model.setApplyNums(APPLY_NUM);

                //时间判定当前时间是否是申购时间时间内
                String openDate = ipo.getOpenDate();
                String closeDate = ipo.getCloseDate();
                boolean currentDateWithinRange = DateUtils.isWithInTheRange(openDate.substring(0, 10), closeDate.substring(0, 10));
                if (!currentDateWithinRange) {
                    return ServerResponse.createByErrorMsg("The current time is not within the purchase date");
                }

                // 获取交易所
                String market = getFirstMarket(ipo.getExchange());
                // 发行价格
                BigDecimal issuePrice = new BigDecimal(ipo.getIssuePrice());
//                if ("SH".equalsIgnoreCase(market) || "SZ".equalsIgnoreCase(market) ) {
//                    SiteSetting siteSetting = this.iSiteSettingService.getSiteSetting();
//                    issuePrice = issuePrice.multiply(new BigDecimal(siteSetting.getRupeesToDollarsRate())).setScale(6, RoundingMode.HALF_UP);
//                }

                // 判断系统版本 印度版本 目前可以赊账购买
//                if (SystemVersionEnum.global.name().equals(active) || SystemVersionEnum.dev.name().equals(active)){
//                    // 目前可以赊账
////                    if (user.getEnableAmt().compareTo(new BigDecimal(model.getApplyNums()).multiply(issuePrice)) < 0) {
////                        return ServerResponse.createByErrorMsg("The user's available balance is insufficient, and the purchase conditions are not met.");
////                    }
//
//                    // 购买规模
//                    String lotSize = ipo.getLotSize();
//                    if (model.getApplyNums() == null || model.getApplyNums() > Integer.parseInt(lotSize)) {
//                        return ServerResponse.createByErrorMsg("The purchase quantity is abnormal or greater than " + ipo.getLotSize());
//                    }
//                } else {
//                    // 申购数量 通用版本是默认可用资金能买多少买多少
//                    int applyNums =  user.getEnableAmt().divide(issuePrice, RoundingMode.DOWN).intValue();
//                    if (applyNums == 0){
//                        return ServerResponse.createByErrorMsg("Your available balance is insufficient.");
//                    }
//                    model.setApplyNums(applyNums);
//                }

                // 购买需要的金额
                BigDecimal buyAmount = new BigDecimal(model.getApplyNums()).multiply(issuePrice);
                BigDecimal enableAmt = user.getEnableAmt();

                if (buyAmount.compareTo(enableAmt) > 0) {
                    paymentAmount = buyAmount.subtract(enableAmt);
                    // 用户可用资金置为0
                    user.setEnableAmt(BigDecimal.ZERO);
                }else {
                    user.setEnableAmt(enableAmt.subtract(buyAmount));
                }

                // 中签时扣款
//                int u = userMapper.updateById(user);
//                if (u <= 0) {
//                    return ServerResponse.createByErrorMsg("Unknown reason, the purchase failed.");
//                }

                model.setUserId(user.getId());
                model.setNewCode(ipo.getSymbol());
                model.setNewName(ipo.getName());
                model.setAgentId(user.getAgentId());
                model.setAgentName(user.getAgentName());
                model.setPhone(user.getPhone());
                model.setBuyPrice(issuePrice);
                model.setBond(buyAmount);
                model.setRealName(Objects.equals(user.getRealName(), "")||user.getRealName()==null ?"The simulated user has no real name":user.getRealName());
                model.setAddTime(new Date());
                model.setOrderNo(KeyUtils.getUniqueKey());
                model.setType(0); // 0 无需补缴 1 需要补缴
            }
            ret = userStockSubscribeMapper.insert(model);
            if (ret > 0) {
                return ServerResponse.createBySuccessMsg("Successful application");
            } else {
                return ServerResponse.createByErrorMsg("The purchase failed.");
            }
        }
        return ServerResponse.createByErrorMsg("Not logged in");
    }

    @Override
    public int update(UserStockSubscribe model) {
        int ret = userStockSubscribeMapper.update1(model);
        return ret>0 ? ret: 0;
    }

    private String getFirstMarket(String exchange){
        if (!exchange.contains(",")){
            exchange = exchange.replace(" ", ", ");
        }
        String[] a = exchange.split(",");
        exchange = a[0];
        return exchange;
    }

    /**
     * admin 新股申购-添加和修改
     */
    @Override
    @Transactional
    public ServerResponse save (UserStockSubscribe model, HttpServletRequest request) {

        int ret = 0;
        log.info("admin 新股申购-添加和修改: " + model);

        if( model.getId() != null  ){
            // 设置中签审核时间
            if (model.getStatus() == 3 || model.getStatus() == 2) {
                model.setEndTime(DateTimeUtil.getCurrentDate());
            }

            Integer applyNumber = model.getApplyNumber();
            if(model.getStatus() == 3 && (applyNumber == null || applyNumber == 0)){
                return ServerResponse.createByErrorMsg("The successful number of hits can not be 0!");
            }

            // 查询当前新股申购记录
            UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.load(model.getId());
            if (userStockSubscribe.getStatus() == 3 && model.getStatus() == 3)  {
                return ServerResponse.createByErrorMsg("The stock has been signed.");
            }
            if (userStockSubscribe.getStatus() == 5) {
                return ServerResponse.createByErrorMsg("The position has been transferred.");
            }

            StIpo ipo = stIpoMapper.selectById(userStockSubscribe.getIpoId());

            // 获取交易所
            String market = getFirstMarket(ipo.getExchange());
            BigDecimal issuePrice = new BigDecimal(ipo.getIssuePrice());
//            if ("SH".equalsIgnoreCase(market) || "SZ".equalsIgnoreCase(market) ) {
//                SiteSetting siteSetting = this.iSiteSettingService.getSiteSetting();
//                issuePrice = issuePrice.multiply(new BigDecimal(siteSetting.getRupeesToDollarsRate())).setScale(6, RoundingMode.HALF_UP);
//            }

            // 设置已中签
            if (model.getStatus() == 3 && model.getApplyNumber() != null){
                if(Integer.parseInt(ipo.getLotSize()) < model.getApplyNumber()){
                    return ServerResponse.createByErrorMsg("The number of winning signatures exceeds the maximum number of applications");
                }
                // 申购数量
                Integer applyNums = model.getApplyNums();
                // 中签数量
                Integer successfulNumber = model.getApplyNumber();
                if(successfulNumber == 0){
                    return ServerResponse.createByErrorMsg("The number of hits can not be 0!");
                }
                if (applyNums < successfulNumber) {
                    return ServerResponse.createByErrorMsg("The number of the lot can not be greater than the number of requisitions!");
                }

                // 中签金额
                BigDecimal successfulAmount = issuePrice.multiply(BigDecimal.valueOf(successfulNumber));

                // 申购ID
                Integer subscribeId = userStockSubscribe.getId();
                User user = userMapper.selectByPrimaryKey(userStockSubscribe.getUserId());
                if (null == user) {
                    return ServerResponse.createByErrorMsg("The user does not exist!");
                }

                // 用户可用资金
                BigDecimal enableAmt = user.getEnableAmt();

                // 中签金额减去用户可用资金 是否大于0  大于0  说明需要补充代缴
                BigDecimal paymentAmount = successfulAmount.subtract(enableAmt);
                if(paymentAmount.compareTo(BigDecimal.ZERO) > 0){
                    // 状态置为需要补缴
                    model.setType(1);

                    // 添加申购记录
                    UserStockSubscribePayment subscribePayment = new UserStockSubscribePayment();
                    subscribePayment.setSubscribeId(subscribeId);
                    subscribePayment.setAmount(paymentAmount);
                    subscribePayment.setPaymentAmount(paymentAmount);
                    subscribePayment.setType(UserStockSubscribePayment.TYPE_SUCCESSFUL);
                    subscribePayment.setCreateTime(new Date());
                    userStockSubscribePaymentMapper.insert(subscribePayment);

                    // 用户可用资金置为0
                    user.setEnableAmt(BigDecimal.ZERO);
                    userMapper.updateByPrimaryKey(user);
                }else {
                    // 状态置为无需补缴
                    model.setType(0);
                    user.setEnableAmt(enableAmt.subtract(successfulAmount));
                    userMapper.updateByPrimaryKey(user);
                }

                // 存储资金记录
                UserCashDetail ucd = new UserCashDetail();
                ucd.setPositionId(model.getId());
                ucd.setAgentId(user.getAgentId());
                ucd.setAgentName(user.getAgentName());
                ucd.setUserId(user.getId());
                ucd.setUserName(user.getRealName());
                ucd.setDeType("winning deduction");
                ucd.setDeAmt(successfulAmount.multiply(new BigDecimal("-1")));
                ucd.setDeSummary(user.getNickName() + " buy stock，" + model.getNewCode() + "/" + model.getNewName() + ", Deduction amount：" + successfulAmount);
                ucd.setAddTime(DateTimeUtil.getCurrentDate());
                ucd.setIsRead(Integer.valueOf(0));
                userCashDetailMapper.insert(ucd);

                // 更新最终的中签金额
                model.setBond(successfulAmount);
                ret = userStockSubscribeMapper.update1(model);

            }
            // 设置未中签
            else if (model.getStatus() == 2){
                model.setApplyNumber(0);
                ret = userStockSubscribeMapper.update1(model);
            }
            // 转持仓
            else if (model.getStatus() == 5){
                return iUserPositionService.newStockToPosition(model.getId(), model.getNewCode());
            }


            // 已中签 发送消息提醒
            if(ret > 0 && model.getStatus() == 3 ){
                //给用户推送消息
                SiteMessage siteMessage = new SiteMessage();
                siteMessage.setUserId(userStockSubscribe.getUserId());
                siteMessage.setUserName(userStockSubscribe.getRealName());
                siteMessage.setTypeName("新股申购");
                siteMessage.setStatus(1);
                siteMessage.setAddTime(DateTimeUtil.getCurrentDate());
                User user = userMapper.selectByPrimaryKey(userStockSubscribe.getUserId());

                siteMessage.setContent("【新股申购中签】恭喜您【"+user.getNickName()+"】，新股申购"+model.getNewCode()+"中签成功，中签金额："+ model.getBond() + "，请及时关注哦。");
                iSiteMessageService.insert(siteMessage);

            }else if(ret > 0 && model.getStatus() == 2) {
                // 申购ID
                User user = userMapper.selectByPrimaryKey(userStockSubscribe.getUserId());

                SiteMessage siteMessage = new SiteMessage();
                siteMessage.setUserId(userStockSubscribe.getUserId());
                siteMessage.setUserName(userStockSubscribe.getRealName());
                siteMessage.setTypeName("新股申购");
                siteMessage.setStatus(1);
                siteMessage.setContent("【新股申购未中签】很遗憾，您【"+user.getNickName()+"】的新股申购"+model.getNewCode()+"本次未中签，申购金额：" + userStockSubscribe.getBond() + "已退还。");
                siteMessage.setAddTime(DateTimeUtil.getCurrentDate());
                iSiteMessageService.insert(siteMessage);

            }
        }
        // 后台新增申购记录
        else{
            if(model.getPhone() != null && model.getId() == null) {
                User user = userMapper.findByPhoneOrEmail(model.getPhone());
                if (user == null) {
                    return ServerResponse.createByErrorMsg("User does not exist");
                }

                model.setRealName(user.getRealName());
                model.setUserId(user.getId());
                model.setAgentId(user.getAgentId());
                model.setAgentName(user.getAgentName());

                // TODO 后台需要改为下拉，不能使用股票代码，因为股票代码好多为空，不能确定唯一代码值
                Integer ipoId = model.getIpoId();
                StIpo ipo = stIpoMapper.selectById(ipoId);
                if (ipo == null) {
                    return ServerResponse.createByErrorMsg("Failure, new stock information does not exist.");
                }

                model.setNewName(ipo.getName());
                model.setBuyPrice(new BigDecimal(ipo.getIssuePrice()));
                if (model.getApplyNums() > Integer.parseInt(ipo.getLotSize()) || model.getApplyNumber() > Integer.parseInt(ipo.getLotSize())) {
                    return ServerResponse.createByErrorMsg("The maximum number of requisitions or winning lots is " + ipo.getLotSize());
                }

                model.setBond(model.getBuyPrice().multiply(BigDecimal.valueOf(model.getApplyNumber())));
                model.setAddTime(DateTimeUtil.getCurrentDate());
                model.setOrderNo(KeyUtils.getUniqueKey());
                model.setType(1);// 1新股申购 2线下配售
                ret = userStockSubscribeMapper.insert(model);
            }
        }

        if(ret > 0){
            return ServerResponse.createBySuccessMsg("Successful operation");
        }
        return ServerResponse.createByErrorMsg("Operation failed");
    }

    /**
     * 发送站内信
     */
    @Override
    public ServerResponse sendMsg(UserStockSubscribe model, HttpServletRequest request) {
        int ret = 0;

        if(model!=null){
            //所有人发站内信
            if(model.getUserId() == 0){
                List<User> users = this.userMapper.selectList(new QueryWrapper<User>());
                for(int k=0;k<users.size();k++){
                    User user = users.get(k);
                    SiteMessage siteMessage = new SiteMessage();
                    siteMessage.setUserId(user.getId());
                    siteMessage.setUserName(user.getRealName());
                    siteMessage.setTypeName("站内消息");
                    siteMessage.setStatus(1);
                    siteMessage.setContent("【站内消息】"+ model.getRemarks() );
                    siteMessage.setAddTime(DateTimeUtil.getCurrentDate());
                    ret = iSiteMessageService.insert(siteMessage);
                }
            } else {
                //指定用户发站内信
                User user = userMapper.selectByPrimaryKey(model.getUserId());
                SiteMessage siteMessage = new SiteMessage();
                siteMessage.setUserId(user.getId());
                siteMessage.setUserName(user.getRealName());
                siteMessage.setTypeName("站内消息");
                siteMessage.setStatus(1);
                siteMessage.setContent("【站内消息】"+ model.getRemarks() );
                siteMessage.setAddTime(DateTimeUtil.getCurrentDate());
                ret = iSiteMessageService.insert(siteMessage);
            }
        }
        if(ret>0){
            return ServerResponse.createBySuccessMsg("Successful operation");
        }
        return ServerResponse.createByErrorMsg("Operation failed");
    }


    /*新股申购-查询列表*/
    @Override
    public ServerResponse<PageInfo> getList(int pageNum, int pageSize, String keyword, String beginTime, String endTime,  Integer status, HttpServletRequest request){
        PageHelper.startPage(pageNum, pageSize);

        Timestamp begin_time = null;
        if (StringUtils.isNotBlank(beginTime)) {
            begin_time = DateTimeUtil.searchStrToTimestamp(beginTime);
        }
        Timestamp end_time = null;
        if (StringUtils.isNotBlank(endTime)) {
            end_time = DateTimeUtil.searchStrToTimestamp(endTime);
        }

        List<StockSubscribeVo> listData = this.userStockSubscribeMapper.pageList(pageNum, pageSize, keyword, begin_time, end_time, status);
        PageInfo pageInfo = new PageInfo(listData);
        pageInfo.setList(listData);
        return ServerResponse.createBySuccess(pageInfo);
    }

    /*新股申购-查询详情*/
    @Override
    public ServerResponse getDetail(int id) {
        return ServerResponse.createBySuccess(this.userStockSubscribeMapper.load(id));
    }

    /*新股申购-查询用户最新新股申购数据*/
    @Override
    public ServerResponse getOneSubscribeByUserId(String type,HttpServletRequest request) {
        String property = PropertiesUtil.getProperty("user.cookie.name");
        String header = request.getHeader(property);
        if (header != null) {
            String userJson = RedisShardedPoolUtils.get(header);
            User user = (User) JsonUtil.string2Obj(userJson, User.class);
            if (user == null) {
                return ServerResponse.createByErrorMsg("Not logged in");
            }

            QueryWrapper<UserStockSubscribe> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", user.getId());

            List<UserStockSubscribe> userStockSubscribes = this.userStockSubscribeMapper.selectList(queryWrapper);
            return ServerResponse.createBySuccess(userStockSubscribes);
        }
        return ServerResponse.createByErrorMsg("Please log in first.");
    }

    /**
     * 获取新股购买详情
     * @param id
     * @param request
     * @return
     */
    @Override
    public ServerResponse getSubscribeDetailById(Integer id, HttpServletRequest request) {
        User user = iUserService.getCurrentRefreshUser(request);
        if (user == null) {
            return ServerResponse.createByErrorMsg("Not logged in");
        }
        val subscribeDetail = userStockSubscribeMapper.getSubscribeDetailById(id);
        return ServerResponse.createBySuccess(subscribeDetail);
    }

    /**
     * 新股申购-用户提交金额
     */
    @Override
    @Transactional
    public ServerResponse userSubmit(Integer id,HttpServletRequest request) {
        int ret = 0;
        String property = PropertiesUtil.getProperty("user.cookie.name");
        String header = request.getHeader(property);

        if (header != null) {
            String userJson = RedisShardedPoolUtils.get(header);
            User user = (User) JsonUtil.string2Obj(userJson, User.class);
            if (user == null) {
                return ServerResponse.createByErrorMsg("Not logged in");
            }
            if(id == null){
                return ServerResponse.createByErrorMsg("Parameter error");
            }

            UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.load(id);
            log.info("userStockSubscribe:{}", userStockSubscribe);

            if (userStockSubscribe != null && userStockSubscribe.getUserId().equals(user.getId())) {

                StIpo ipo = stIpoMapper.selectById(userStockSubscribe.getIpoId());

                boolean currentDateWithinRange = DateUtils.isWithInTheRange(ipo.getOpenDate(), ipo.getCloseDate());
                if (!currentDateWithinRange) {
                    return ServerResponse.createByErrorMsg("The current time is not within the purchase date");
                }

                // 中签状态 需要认缴
                if (userStockSubscribe.getStatus() == 3) {
                    userStockSubscribe.setSubmitTime(DateTimeUtil.getCurrentDate());
                    userStockSubscribe.setStatus(4);

                    User user1 = userMapper.selectByPrimaryKey(userStockSubscribe.getUserId());
                    if (user1.getEnableAmt().compareTo(userStockSubscribe.getBond()) < 0) {
                        return ServerResponse.createByErrorMsg("No Money No Happy");
                    }

                    log.info("原可用资金"+user1.getEnableAmt());
                    BigDecimal enableAmt = user1.getEnableAmt().subtract(userStockSubscribe.getBond());
                    log.info("enableAmt" + enableAmt);
                    user1.setEnableAmt(enableAmt);
                    log.info("可用资金:" + user1.getEnableAmt()  +",保证金:" + userStockSubscribe.getBond() + ",原djzj:"+user1.getDjzj());
                    if (user1.getDjzj() != null) {
                        user1.setDjzj(user1.getDjzj().add(userStockSubscribe.getBond()));
                    }else {
                        user1.setDjzj(userStockSubscribe.getBond());
                    }
                    ret = userMapper.updateByPrimaryKeySelective(user1);
                }
                else {
                    return ServerResponse.createByErrorMsg("No need to pay if you don't sign.");
                }
            } else {
                return ServerResponse.createByErrorMsg("New stock purchase orders do not exist！");
            }

            if (ret > 0) {
                ret = userStockSubscribeMapper.update1(userStockSubscribe);
                if (ret > 0) {
                    return ServerResponse.createBySuccessMsg("Successful operation");
                } else {
                    return ServerResponse.createByErrorMsg("Operation failed");
                }
            }else {
                return ServerResponse.createByErrorMsg("Deduction failed");
            }
        }
        return ServerResponse.createByErrorMsg("Please log in first.");
    }
    /**
     * 新股申购-删除
     *
     * @param id
     * @param request
     * @return
     */
    @Override
    public ServerResponse del(int id, HttpServletRequest request) {
        int ret = 0;
        if(id>0){
            ret = userStockSubscribeMapper.delete1(id);
        }
        if(ret>0){
            return ServerResponse.createBySuccessMsg("Successful operation");
        }
        return ServerResponse.createByErrorMsg("Operation failed");
    }

    /**
     * 新股抢筹 下单
     */
    @Override
    public ServerResponse buyNewStockQc(String code, Integer num, HttpServletRequest request) {
        User user = this.iUserService.getCurrentRefreshUser(request);

        if (code == null || "".equals(code) || num == null || num <= 0) {
            return ServerResponse.createByErrorMsg("The stock code cannot be empty or the purchase quantity is abnormal.");
        }
        StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("code", code));
        //实名认证开关
        SiteProduct siteProduct = iSiteProductService.getProductSetting();
        if (siteProduct.getRealNameDisplay() && (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()))) {
            return ServerResponse.createByErrorMsg("If the order fails, please authenticate with your real name first.");
        }

        //重复申购限制
//                UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.selectOne(new QueryWrapper<UserStockSubscribe>().eq("new_code", model.getNewCode()).eq("user_id", user.getId()));
//                if (userStockSubscribe != null) {
//                    return ServerResponse.createByErrorMsg("请勿重复申购");
//                }
        if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) {
            return ServerResponse.createByErrorMsg("Order failed and account locked");
        }
        if (stockSubscribe == null) {
            return ServerResponse.createByErrorMsg("New stock code does not exist");
        }


        if ("sh".equals(stockSubscribe.getStockType())||"sh".equals(stockSubscribe.getStockType())&& num < 1000){
            return ServerResponse.createByErrorMsg("The minimum number of new shares in Shanghai is 1,000 shares.");
        }else if ("sz".equals(stockSubscribe.getStockType())||"sz".equals(stockSubscribe.getStockType())&&num < 500){
            return ServerResponse.createByErrorMsg("The minimum number of new shares in Shenzhen is 500 shares.");
        }

        if (user.getEnableAmt().compareTo(new BigDecimal(num).multiply(stockSubscribe.getPrice())) < 0) {
            return ServerResponse.createByErrorMsg("The user's available balance is not met.");
        }
        user.setEnableAmt(user.getEnableAmt().subtract(new BigDecimal(num).multiply(stockSubscribe.getPrice())));
//                if (user.getDjzj()!=null) {
//                        user.setDjzj(user.getDjzj().add(new BigDecimal(model.getApplyNums()).multiply(stockSubscribe.getPrice())));
//                }else
//                {
//                        user.setDjzj(new BigDecimal(model.getApplyNums()).multiply(stockSubscribe.getPrice()));
//                }
        int u = userMapper.updateById(user);
        if (u <= 0) {
            return ServerResponse.createByErrorMsg("Unknown reason，The purchase failed.");
        }
        UserStockSubscribe userStockSubscribe = new UserStockSubscribe();
        userStockSubscribe.setUserId(user.getId());
        userStockSubscribe.setNewName(stockSubscribe.getName());
        userStockSubscribe.setAgentId(user.getAgentId());
        userStockSubscribe.setAgentName(user.getAgentName());
        userStockSubscribe.setPhone(user.getPhone());
        userStockSubscribe.setApplyNums(num);
        userStockSubscribe.setNewType(stockSubscribe.getStockType());
        userStockSubscribe.setBuyPrice(stockSubscribe.getPrice());
        userStockSubscribe.setNewCode(stockSubscribe.getCode());
        userStockSubscribe.setBond(new BigDecimal(num).multiply(stockSubscribe.getPrice()));
        userStockSubscribe.setRealName(Objects.equals(user.getRealName(), "")||user.getRealName()==null ?"The simulated user has no real name":user.getRealName());
        userStockSubscribe.setAddTime(new Date());
        userStockSubscribe.setOrderNo(KeyUtils.getUniqueKey());
        userStockSubscribe.setType(3);
        int ret = userStockSubscribeMapper.insert(userStockSubscribe);
        if (ret > 0) {

            return ServerResponse.createBySuccessMsg("Successful purchase and fundraising");
        } else {
            return ServerResponse.createByErrorMsg("Failed to apply for a purchase");
        }
    }
    /**
     * 新股抢筹 股票列表
     */
    @Override
    public ServerResponse getStockQcList(HttpServletRequest request) {
        String nowDate = DateTimeUtil.stampToDate(String.valueOf(System.currentTimeMillis()));
        List<StockSubscribe> stockSubscribeListQc = this.stockSubscribeMapper.selectList(new QueryWrapper<StockSubscribe>().eq("list_date",nowDate));
        return ServerResponse.createBySuccess(stockSubscribeListQc);
    }

    /**
     * 用户新股抢筹列表
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @param request
     * @return
     */
    @Override
    public ServerResponse getQcList(int pageNum, int pageSize, String keyword, HttpServletRequest request) {
        PageHelper.startPage(pageNum, pageSize);
        List<UserStockSubscribe> qcList;
        if (StringUtils.isNotEmpty(keyword)) {
            qcList = userStockSubscribeMapper.selectList(new QueryWrapper<UserStockSubscribe>()
                    .like("phone",keyword)
                    .or().like("new_code",keyword)
                    .or().like("new_name",keyword)
                    .or().like("status",keyword)
                    .eq("type", 3).orderByDesc("add_time"));
        }else {
            qcList = userStockSubscribeMapper.selectList(new QueryWrapper<UserStockSubscribe>().eq("type", 3).orderByDesc("add_time"));
        }
        PageInfo pageInfo = new PageInfo(qcList);
        pageInfo.setList(qcList);
        return ServerResponse.createBySuccess(pageInfo);
    }

    /**
     * 新股抢筹审核
     * @param status
     * @param request
     * @return
     */
    @Override
    public ServerResponse updateQcByAdmin(String id,String status,String num, HttpServletRequest request) {
        if (StringUtils.isEmpty(id)||StringUtils.isEmpty(status)) {
            return ServerResponse.createByErrorMsg("Parameter error");
        }
        UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.selectById(id);
        if (userStockSubscribe == null) {
            return ServerResponse.createByErrorMsg("The record of snatching does not exist");
        }
        User user = userMapper.selectById(userStockSubscribe.getUserId());
        if (user == null) {
            return ServerResponse.createByErrorMsg("User does not exist");
        }

        if(userStockSubscribe.getStatus() == 1){
            if("2".equals(status)){
                user.setEnableAmt(user.getEnableAmt().add(userStockSubscribe.getBond()));
                int ret = userMapper.updateById(user);
                if (ret <= 0) {
                    return ServerResponse.createByErrorMsg("Unknown reason, review failed");
                }
                userStockSubscribe.setStatus(2);
                userStockSubscribe.setEndTime(new Date());
                int ret1 = userStockSubscribeMapper.updateById(userStockSubscribe);
                if (ret1 > 0) {
                    return ServerResponse.createBySuccessMsg("Reviewed Successfully");
                } else {
                    return ServerResponse.createByErrorMsg("Audit failed");
                }
            }else if ("3".equals(status)){
                if (StringUtils.isEmpty(num) || Integer.parseInt(num) <= 0||Integer.parseInt(num)>userStockSubscribe.getApplyNums()) {
                    return ServerResponse.createByErrorMsg("The number of winning signatures cannot be empty and cannot be greater than the number of applications");
                }
                Stock stock = (Stock) this.iStockService.findStockByCode(userStockSubscribe.getNewCode()).getData();
                if (stock == null) {
                    log.info("股票不存在");
                    return ServerResponse.createByErrorMsg("Stock does not exist");
                }
                SiteSetting siteSetting = this.iSiteSettingService.getSiteSetting();
                if (siteSetting == null) {
                    log.error("下单出错，网站设置表不存在");
                    return ServerResponse.createByErrorMsg("The order failed, and the system settings are wrong.");
                }
                BigDecimal buy_amt = (userStockSubscribe.getBuyPrice()).multiply(new BigDecimal(num));
                UserPosition userPosition = new UserPosition();
                userPosition.setPositionType(user.getAccountType());
                userPosition.setPositionSn(KeyUtils.getUniqueKey());
                userPosition.setUserId(user.getId());
                userPosition.setNickName(user.getRealName());
                userPosition.setAgentId(user.getAgentId());
                userPosition.setStockCode(stock.getStockCode());
                userPosition.setStockName(stock.getStockName());
                userPosition.setStockGid(stock.getStockGid());
                userPosition.setStockSpell(stock.getStockSpell());
                userPosition.setBuyOrderId(GeneratePosition.getPositionId());
                userPosition.setBuyOrderTime(new Date());
                userPosition.setBuyOrderPrice(userStockSubscribe.getBuyPrice());
                userPosition.setOrderDirection("Buy Up");
                userPosition.setOrderNum(Integer.valueOf(num));

                if (stock.getStockPlate() != null) {
                    userPosition.setStockPlate(stock.getStockPlate());
                }
                userPosition.setIsLock(Integer.valueOf(0));
                userPosition.setOrderLever(1);
                userPosition.setOrderTotalPrice(buy_amt);

                //递延费特殊处理
                BigDecimal stayFee = userPosition.getOrderTotalPrice().multiply(siteSetting.getStayFee());
                BigDecimal allStayFee = stayFee.multiply(new BigDecimal(1));
                userPosition.setOrderStayFee(allStayFee);
                userPosition.setOrderStayDays(1);


                BigDecimal buy_fee_amt = buy_amt.multiply(siteSetting.getBuyFee()).setScale(2, 4);
                log.info("创建模拟持仓 手续费（配资后总资金 * 百分比） = {}", buy_fee_amt);
                userPosition.setOrderFee(buy_fee_amt);


                BigDecimal buy_yhs_amt = buy_amt.multiply(siteSetting.getDutyFee()).setScale(2, 4);
                log.info("创建模拟持仓 印花税（配资后总资金 * 百分比） = {}", buy_yhs_amt);
                userPosition.setOrderSpread(buy_yhs_amt);
                StockListVO stockListVO = SinaStockApi.assembleStockListVO(SinaStockApi.getSinaStock(stock.getStockGid()));
                BigDecimal now_price = new BigDecimal(stockListVO.getNowPrice());

//                if (now_price.compareTo(new BigDecimal("0")) == 0) {
//                    log.info(stock.getStockGid()+"报价0，");
//                    return ServerResponse.createByErrorMsg("报价0，请稍后再试");
//
//                }

//                double stock_crease = stockListVO.getHcrate().doubleValue();
//                SiteSpread siteSpread = iSiteSpreadService.findSpreadRateOne(new BigDecimal(stock_crease), buy_amt, stock.getStockCode(), now_price);
                BigDecimal spread_rate_amt = new BigDecimal("0");
//                if(siteSpread != null){
//                    spread_rate_amt = buy_amt.multiply(siteSpread.getSpreadRate()).setScale(2, 4);
//                    log.info("用户购买点差费（配资后总资金 * 百分比{}） = {}", siteSpread.getSpreadRate(), spread_rate_amt);
//                } else{
//                    log.info("用户购买点差费（配资后总资金 * 百分比{}） = {}", "设置异常", spread_rate_amt);
//                }

                userPosition.setSpreadRatePrice(spread_rate_amt);


                BigDecimal profit_and_lose = new BigDecimal("0");
                userPosition.setProfitAndLose(profit_and_lose);


                BigDecimal all_profit_and_lose = profit_and_lose.subtract(buy_fee_amt).subtract(buy_yhs_amt).subtract(spread_rate_amt);
                userPosition.setAllProfitAndLose(all_profit_and_lose);


                userPosition.setOrderStayDays(Integer.valueOf(0));
                userPosition.setOrderStayFee(new BigDecimal("0"));
                userPosition.setSpreadRatePrice(new BigDecimal("0"));

                int insertPositionCount = this.userPositionMapper.insert(userPosition);
                if (insertPositionCount > 0) {
                    log.info("【抢筹创建持仓】保存记录成功");
                } else {
                    log.error("【抢筹创建持仓】保存记录出错");
                }

//                iAgentAgencyFeeService.AgencyFeeIncome(1,userPosition.getPositionSn());
                userStockSubscribe.setStatus(3);
                userStockSubscribe.setEndTime(new Date());
                userStockSubscribe.setFixTime(new Date());
                userStockSubscribe.setApplyNumber(Integer.valueOf(num));
                this.userStockSubscribeMapper.updateById(userStockSubscribe);
                BigDecimal reimburse = new BigDecimal(userStockSubscribe.getApplyNums()-Integer.parseInt(num)).multiply(userStockSubscribe.getBuyPrice());
                user.setEnableAmt(user.getEnableAmt().add(reimburse));
                int ret = userMapper.updateById(user);
                if (ret <= 0) {
                    return ServerResponse.createByErrorMsg("Unknown reason, review failed");
                } else {
                    return ServerResponse.createBySuccess("The new stock is approved to transfer to the user's position and order number：" + userPosition.getPositionSn());
                }
            }
        }
        userStockSubscribe.setStatus(Integer.valueOf(status));
        userStockSubscribe.setApplyNumber(Integer.valueOf(num));
        userStockSubscribe.setEndTime(new Date());
        int res = this.userStockSubscribeMapper.updateById(userStockSubscribe);
        if (res <= 0) {
            return ServerResponse.createByErrorMsg("Failed to modify the status");
        } else {
            return ServerResponse.createBySuccessMsg("The state has been modified successfully");
        }
    }

    /**
     * 新股抢筹添加
     * @param phone
     * @param code
     * @param num
     * @param request
     * @return
     */

    @Override
    public ServerResponse addQcByAdmin(String phone, String code, String num, HttpServletRequest request) {
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code) || StringUtils.isEmpty(num)) {
            return ServerResponse.createByErrorMsg("Parameter error");
        }
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", phone));
        if (user == null) {
            return ServerResponse.createByErrorMsg("User does not exist");
        }
        StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("code", code));
        if (stockSubscribe == null) {
            return ServerResponse.createByErrorMsg("New stock code does not exist");
        }
        UserStockSubscribe userStockSubscribe = new UserStockSubscribe();
        userStockSubscribe.setOrderNo(KeyUtils.getUniqueKey());
        userStockSubscribe.setUserId(user.getId());
        userStockSubscribe.setRealName(user.getRealName() == null ? "The simulated user has no real name" : user.getRealName());
        userStockSubscribe.setPhone(user.getPhone());
        userStockSubscribe.setAgentId(user.getAgentId());
        userStockSubscribe.setAgentName(user.getAgentName());
        userStockSubscribe.setNewCode(stockSubscribe.getCode());
        userStockSubscribe.setNewName(stockSubscribe.getName());
        userStockSubscribe.setBond(new BigDecimal(num).multiply(stockSubscribe.getPrice()));
        userStockSubscribe.setBuyPrice(stockSubscribe.getPrice());
        userStockSubscribe.setApplyNums(Integer.valueOf(num));
        userStockSubscribe.setType(3);
        userStockSubscribe.setStatus(1);
        userStockSubscribe.setAddTime(new Date());
        userStockSubscribe.setNewType(stockSubscribe.getStockType());
        int ret = userStockSubscribeMapper.insert(userStockSubscribe);
        if (ret > 0) {
            return ServerResponse.createBySuccessMsg("Added successfully");
        } else {
            return ServerResponse.createByErrorMsg("Failed to add");
        }
    }

    @Override
    public ServerResponse getzqjkl(HttpServletRequest request) {
        User user = this.iUserService.getCurrentRefreshUser(request);
        if (user == null) {
            return ServerResponse.createByErrorMsg("Not logged in");
        }
        List<UserStockSubscribe> userStockSubscribes = userStockSubscribeMapper.selectList(new QueryWrapper<UserStockSubscribe>().eq("phone", user.getPhone()).ge("status", 3).orderByDesc("add_time"));
        return ServerResponse.createBySuccess(userStockSubscribes);
    }

    @Override
    public ServerResponse getAgentList(int pageNum, int pageSize, String keyword, String beginTime, String endTime, Integer status,  HttpServletRequest request) {

        AgentUser currentAgent = this.iAgentUserService.getCurrentAgent(request);
        if (null == currentAgent) {
            return ServerResponse.createByErrorMsg("获取代理信息失败！");
        }

        Integer agentId = currentAgent.getId();
        if (null == agentId) {
            return ServerResponse.createByErrorMsg("获取代理信息失败： 【agentId为空】");
        }

        PageHelper.startPage(pageNum, pageSize);

        Timestamp begin_time = null;
        if (StringUtils.isNotBlank(beginTime)) {
            begin_time = DateTimeUtil.searchStrToTimestamp(beginTime);
        }
        Timestamp end_time = null;
        if (StringUtils.isNotBlank(endTime)) {
            end_time = DateTimeUtil.searchStrToTimestamp(endTime);
        }

        List<UserStockSubscribe> listData = this.userStockSubscribeMapper.pageListByAgent(pageNum, pageSize, keyword, agentId, begin_time, end_time, status);
        PageInfo pageInfo = new PageInfo(listData);
        pageInfo.setList(listData);
        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    @Transactional
    public ServerResponse paymentStockSubscribe(Integer id, HttpServletRequest request) {

        int ret = 0;
        UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.load(id);
        log.info("userStockSubscribe:{}", userStockSubscribe);

        if (userStockSubscribe != null) {
            StIpo ipo = stIpoMapper.selectById(userStockSubscribe.getIpoId());
            if (ipo == null) {
                return ServerResponse.createByErrorMsg("IPO does not exist");
            }

            Integer userId = userStockSubscribe.getUserId();
            User user = userMapper.selectById(userId);
            if (user == null) {
                return ServerResponse.createByErrorMsg("User does not exist");
            }

            // 查询当前用户 该IPO订单还需要补缴多少钱
            Integer subscribeId = userStockSubscribe.getId();
            UserStockSubscribePayment payment = userStockSubscribePaymentMapper.selectBySubscribeId(subscribeId);
            if(null == payment){
                return ServerResponse.createByErrorMsg("The user does not need to pay up");
            }

            BigDecimal paymentAmount = payment.getPaymentAmount();
            if (paymentAmount.compareTo(BigDecimal.ZERO) <= 0) {
                return ServerResponse.createByErrorMsg("The user has already paid the remaining amount");
            }

            // 计算用户当前可用余额
            BigDecimal enableAmt = user.getEnableAmt();

            // 用户钱还不够
            if (paymentAmount.compareTo(enableAmt) > 0) {
                BigDecimal subtract = paymentAmount.subtract(enableAmt);

                Integer status = userStockSubscribe.getStatus();
                // 如果是已认购状态  那么这时候补缴金额需要加到冻结资金里面 方便后续不中签的时候退款
                user.setEnableAmt(BigDecimal.ZERO);
                userMapper.updateById(user);

                // 新增一条补缴记录
                UserStockSubscribePayment subscribePayment = new UserStockSubscribePayment();
                subscribePayment.setSubscribeId(subscribeId);
                subscribePayment.setAmount(enableAmt);
                subscribePayment.setPaymentAmount(subtract);
                subscribePayment.setType(UserStockSubscribePayment.TYPE_PAYMENT);
                subscribePayment.setCreateTime(new Date());
                userStockSubscribePaymentMapper.insert(subscribePayment);
                return ServerResponse.createBySuccess("用户补缴" + enableAmt + "元, 剩余" + paymentAmount.subtract(enableAmt) + "元待补缴!");
            } else {
                // 用户钱够
                Integer status = userStockSubscribe.getStatus();
                // 如果是已认购状态  那么这时候补缴金额需要加到冻结资金里面 方便后续不中签的时候退款
                user.setEnableAmt(enableAmt.subtract(paymentAmount));
                userMapper.updateById(user);

                // 更新IPO订单的待补缴状态为正常
                userStockSubscribe.setType(0);
                userStockSubscribeMapper.updateById(userStockSubscribe);

                // 新增一条补缴记录
                UserStockSubscribePayment subscribePayment = new UserStockSubscribePayment();
                subscribePayment.setSubscribeId(subscribeId);
                subscribePayment.setAmount(paymentAmount);
                subscribePayment.setPaymentAmount(BigDecimal.ZERO);
                subscribePayment.setType(UserStockSubscribePayment.TYPE_PAYMENT);
                subscribePayment.setCreateTime(new Date());
                userStockSubscribePaymentMapper.insert(subscribePayment);
                return ServerResponse.createBySuccess("用户补缴" + paymentAmount + "元, 剩余" + 0 + "元待补缴!");
            }

        } else {
            return ServerResponse.createByErrorMsg("New stock purchase orders do not exist！");
        }
    }
}